﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FCS;

namespace Applications
{
    public class Primes : BaseListFunc<int>
    {
        /// <summary>
        ///   primes :: [Int] -> [Int]
        ///     primes (n:ns) = n : primes (filter (\v -> v `mod` n /= 0) ns)
        /// </summary>
        /// <returns></returns>
        public Primes(IFunList<int> list) :
            base(list, (n, ns) => Cons(n, this.Primes(Filter(v => v % n != 0, ns))))
        {
        }
    }

    public class Factorial : BaseCaseFunc<int>
    {
        /// <summary>
        /// (defun fact (n)
        ///     (cond 
        ///         ((equal n 0) 1)
        ///         (t (* n (fact (- n 1))))))
        /// </summary>
        /// <param name="n"></param>
        public Factorial(int n)
        {
            Case(() => n == 0, () => 1);
            Case(() => true, () => n * this.Factorial(n - 1));
        }
    }

    public class Fibonacci : BaseCaseFunc<int>
    {
        //fib :: Integer -> Integer
        //fib n
        //    | n == 0  = 0
        //    | n == 1  = 1
        //    | n  > 1  = fib (n-1) + fib (n-2)
        public Fibonacci(int n)
        {
            Case(() => n == 0, () => 0);
            Case(() => n == 1, () => 1);
            Case(() => n > 1, () => this.Fibonacci(n - 1) + this.Fibonacci(n - 2));
        }
    }
}
